package com.lancoo.answer.view.fragment.correctmistake

import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.Rect
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.SparseArray
import android.view.KeyEvent
import android.view.View
import android.view.ViewTreeObserver
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.lancoo.answer.R
import com.lancoo.answer.databinding.EvFmtGctPracticeBinding
import com.lancoo.answer.model.bean.ModelAnswerArea
import com.lancoo.answer.model.bean.ModelAnswerInfo
import com.lancoo.answer.model.bean.Ques
import com.lancoo.answer.model.bean.TextInfo
import com.lancoo.answer.util.*
import com.lancoo.answer.view.adapter.CorrectMistakesTextAdapter
import com.lancoo.answer.view.base.BaseBindingFragment
import com.lancoo.answer.widget.DrawView
import com.lancoo.answer.widget.NewEditInputView
import com.lancoo.answer.widget.PopupList
import java.util.regex.Pattern

/**
 * Created by wealive on 2021/9/25.
 *
 *
 */
class SameCorrectMistakesFragment(
    val activity: AppCompatActivity,
    val sameQuesDetail: List<Ques>,
    val index_A: Int
) : BaseBindingFragment<EvFmtGctPracticeBinding>(), PopupList.PopupListListener {
    private val popupMenuItemList = arrayListOf<String>()
    private val tvMap = SparseArray<View>()
    private val itemAnswer = ArrayList<String>()
    private val askList = ArrayList<TextInfo>()
    private val screenHeight by lazy { DensityUtils.getScreenHeight(requireContext()) }
    private var questContent = ""
    private val textInfoList = mutableListOf<TextInfo>()
    private lateinit var adapter: CorrectMistakesTextAdapter
    private var answerInfoList = mutableListOf<ModelAnswerInfo>()
    private lateinit var inputPopupWindow: NewEditInputView
    private var currentOperateIndex = -1 //当前操作的单词下标
    private var remaindStyle = false
    private var currentRalY = 0
    private var lastRalY = 0
    private var GenreType = 0
    private var GenreID = 0
    private var answerArea = mutableListOf<ModelAnswerArea>()
    private lateinit var inputManager: InputManager


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initAnswerData()
    }

    /*初始化题干及参考答案*/
    private fun initAnswerData() {
        GenreType = sameQuesDetail[index_A].GenreType!!.toInt()
        GenreID = sameQuesDetail[index_A].GenreID!!.toInt()
        val answerAreaList =
            sameQuesDetail[index_A].ModelAnswerAreaList!!
        for (i in answerAreaList.indices) {
            val area = answerAreaList[i]
            answerArea.add(area)
        }
        textInfoList.addAll(
            sameQuesDetail[index_A].ModelTextInfoList!!
        )
        answerInfoList.addAll(
            sameQuesDetail[index_A].ModelAnswerInfoList!!
        )
        val subChildItemBeanXList =
            sameQuesDetail[index_A].ChildList!![0].ItemList!!
        for (i in answerInfoList.indices) {
            subChildItemBeanXList[i].StuAnswer = ""
            val strs = answerInfoList[i].Answer!!.split("$|")
            for (j in strs.indices) {
                val answerInfo = strs[j].split("*|")
                val position = answerInfo[0]
                if (!itemAnswer.contains(position)) {
                    itemAnswer.add(position)
                }
            }
        }


        /*插入参考答案及初始化学生作答*/
        for (i in subChildItemBeanXList.indices) {
            val itemBeanX = subChildItemBeanXList[i]
            if (!itemBeanX.ItemAnswer!!.contains("@")) {
                itemBeanX.ItemAnswer = answerInfoList[i].Answer + "@|" + itemBeanX.ItemAnswer
            }
        }
    }

    @SuppressLint("SetTextI18n")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        if (sameQuesDetail[index_A].QuesIndexText!!.isNotEmpty()) {
            binding.tvLeader.text = HtmlUtils.setText(sameQuesDetail[index_A].QuesIndexText!!)
            binding.tvLeader.visibility = View.VISIBLE
        } else {
            binding.tvLeader.visibility = View.INVISIBLE
        }
        inputManager = InputManager(context)
        adapter = CorrectMistakesTextAdapter(0, requireContext(), textInfoList, answerArea)
        binding.fl.setAdapter(adapter)
        if (answerArea.size > 1) {
            for (i in textInfoList.indices) {
                drawArea(i)
            }
        } else if (sameQuesDetail[index_A].ChildList!![0].ItemList!!.size == 1) {
            binding.tvIndex.text =
                "${sameQuesDetail[index_A].ChildList!![0].ItemList!![0].ItemSortIndex}."
        }
        requireActivity().window.decorView.viewTreeObserver.addOnGlobalLayoutListener(
            mGlobalLayoutListener
        )
        binding.fl.setOnItemClickListener { position, view ->
            inputManager.hideALlSoftInput()
            val textInfo = textInfoList[position]
            val patPunc = Pattern.compile("[\"'.,...:!?;—-]")
            val matcher = patPunc.matcher(textInfo.Text)
            if (matcher.find() && textInfo.Text.length <= 2) {
                return@setOnItemClickListener
            }
            var enableClick = false
            if (GenreType != 3) {
                answerArea.forEach {
                    if (textInfo.Index in it.AnswerArea!!.split("-")[0].toInt()..it.AnswerArea!!.split(
                            "-"
                        )[1].toInt()
                    ) {
                        enableClick = true
                    }
                }
                if (!enableClick) {
                    return@setOnItemClickListener
                }
            }
            if (!(GenreID == 48 && GenreType == 2) && !(GenreID == 46 && GenreType == 2)) {
                if (textInfo.stuType == -1 && askList.size >= answerInfoList.size) {
                    ToastTool.showWithClick(requireContext(), "最多有${answerInfoList.size}处错误")
                    return@setOnItemClickListener
                }
            }
            currentOperateIndex = position
            val location = IntArray(2)
            view.getLocationInWindow(location)
            setPopupMenuData(position, textInfo.stuType)
            var isArea = false
            answerArea.forEach {
                if (textInfo.Index == it.AnswerArea!!.split("-")[0].toInt() && answerArea.size > 1) {
                    isArea = true
                }
            }
            val x = if (isArea) {
                location[0] + view.width / 2 + DpUtils.dip2px(requireContext(), 8f)
            } else {
                location[0] + view.width / 2
            }
            val y = location[1] - view.height
            textInfo.x = x
            textInfo.y = y + view.height
            view.findViewById<TextView>(R.id.tv_text)
                .setBackgroundColor(Color.parseColor("#330099ff"))
            showPopupMenuWindow(position, x, y)
        }
    }

    private val mGlobalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
        val r = Rect()
        // 使用最外层布局填充，进行测算计算
        binding.dsv.getWindowVisibleDisplayFrame(r)
//        val svHeight = binding.dsv.height
        val heightDiff = screenHeight - r.bottom
        if (heightDiff > 100 && lastRalY != currentRalY) {
            lastRalY = currentRalY
            Handler(Looper.getMainLooper()).post {
                binding.dsv.smoothScrollTo(
                    0,
                    binding.dsv.scrollY + currentRalY - screenHeight + heightDiff + DensityUtils.dp2px(
                        context, 90f
                    )
                )
            }
        }
        if (heightDiff == 0 && lastRalY == currentRalY) {
            lastRalY = 0
        }
    }

    private fun setPopupMenuData(position: Int, type: Int) {
        popupMenuItemList.clear()
        when (type) {
            -1 -> {
                if (getAnswerType(position) == 4) {
                    popupMenuItemList.add("取消")
                } else {
                    popupMenuItemList.add("删除")
                    popupMenuItemList.add("修改")
                    popupMenuItemList.add("前增")
                    popupMenuItemList.add("后增")
                    if (GenreID == 48 && GenreType == 2 || GenreID == 49 && GenreType == 5) {
                        popupMenuItemList.add("无错")
                    }
                }
            }

            0, 4 -> popupMenuItemList.add("取消")
            1, 2, 3 -> {
                popupMenuItemList.add("取消")
                popupMenuItemList.add("编辑")
            }
        }
    }

    /*绘制编号*/
    private fun drawArea(position: Int) {
        answerArea.forEachIndexed { index, it ->
            if (it.AnswerArea!!.split("-")[0].toInt() == textInfoList[position].Index) {
                val child = binding.fl.getChildAt(position)
                val tvIndex =
                    DrawView(
                        false,
                        false,
                        child,
                        sameQuesDetail[index_A].ChildList!![0].ItemList!![if (sameQuesDetail[index_A].ChildList!![0].ItemList!!.size > 1) index else 0].ItemSortIndex!!,
                        "",
                        -1,
                        1,
                        requireContext()
                    )
                binding.flLayout.addView(tvIndex)
            }
        }
    }

    private fun showPopupMenuWindow(position: Int, mRawX: Int, mRawY: Int) {
        val popupList = PopupList(requireContext())
        popupList.showPopupListWindow(
            binding.flLayout, position, mRawX.toFloat(), mRawY.toFloat(),
            popupMenuItemList, this
        )
    }

    override fun showPopupList(
        adapterView: View?,
        contextView: View?,
        contextPosition: Int
    ): Boolean {
        return true
    }

    override fun onPopupListClick(contextView: View?, contextPosition: Int, position: Int) {
        operateAnswer(contextPosition, position)
    }

    /**
     * @param position 操作单词下标
     * @param operateType  操作类型 0--删除 1--修改 2--前增 3--后增4--无错
     */
    private fun operateAnswer(position: Int, operateType: Int) {
        val textInfo: TextInfo = textInfoList[position]
        val childAt: View = binding.fl.getChildAt(position)
        val tvText = childAt.findViewById<TextView>(R.id.tv_text)
        var startPosition = -1
        var endPosition = -1
        answerArea.forEach {
            if (textInfo.Index in it.AnswerArea!!.split("-")[0].toInt()..it.AnswerArea!!.split("-")[1].toInt()) {
                startPosition = it.AnswerArea!!.split("-")[0].toInt()
                endPosition = it.AnswerArea!!.split("-")[1].toInt()
            }
        }
        when (popupMenuItemList[operateType]) {
            "取消" -> { //有过作答
                deleteAnswer(
                    startPosition,
                    endPosition,
                    position
                )
            }

            "删除" -> {
                if ((GenreID == 48 && GenreType == 2) || (GenreID == 46 && GenreType == 2)) {
                    if (hasAnswer(position)) {
                        val answerPosition = getAnswerPosition(position)
                        val view = tvMap[answerPosition]
                        askList.remove(textInfoList[answerPosition])
                        binding.flLayout.removeView(view)
                        tvMap.remove(answerPosition)
                        textInfoList[answerPosition].stuType = -1
                        textInfoList[answerPosition].stuAnswer = ""
//                        textInfoList[answerPosition].Index = "-1"
                        textInfoList[answerPosition].digitalAnswer = ""
                    }
                }
                tvText.setBackgroundColor(Color.TRANSPARENT)
                textInfo.stuType = operateType
                textInfo.stuAnswer = ""
//                textInfo.Index = position.toString()
                val answerStr = FormatUtil.toStr(position, textInfoList)
                val str = FormatUtil.toArr(textInfo, answerStr)
                textInfo.digitalAnswer = str
                askList.add(textInfo)
                insertStuAnswer(askList)
                drawAnswer(position, textInfo, childAt, mutableListOf())
            }

            "修改", "前增", "后增", "编辑" -> {
                showEditInputPopupWindow(
                    position,
                    if (popupMenuItemList[operateType] == "编辑") textInfo.stuType else operateType,
                    textInfo.stuAnswer
                )
//                showAnimation()
                remaindStyle = true
            }

            "无错" -> {
                val viewList = mutableListOf<View>()
                textInfoList.forEachIndexed { index, textInfo ->
                    if (textInfo.Index in startPosition..endPosition) {
                        if (textInfoList[index].stuType != -1) {
                            askList.remove(textInfoList[index])
                            textInfoList[index].stuType = -1
                            textInfoList[index].stuAnswer = ""
//                        textInfoList[i].Index = "-1"
                            textInfoList[index].digitalAnswer = ""
                            val view = tvMap[index]
                            binding.flLayout.removeView(view)
                            tvMap.remove(index)
                        }
                        viewList.add(binding.fl.getChildAt(index))
                    }
                }
                tvText.setBackgroundColor(Color.TRANSPARENT)
                textInfo.stuType = 4
                textInfo.stuAnswer =
                    if (viewList.size > 1) "$startPosition-$endPosition*|4*|@|√" else "$startPosition*|4*|@|√"
//                textInfo.Index = "$startPosition-$endPosition"
                textInfo.digitalAnswer =
                    if (viewList.size > 1) "$startPosition-$endPosition*|4*|@|√" else "$startPosition*|4*|@|√"
                askList.add(textInfo)
                insertStuAnswer(askList)
                drawAnswer(position, textInfo, childAt, viewList)
            }
        }
    }

    /*作答输入弹窗*/
    private fun showEditInputPopupWindow(
        position: Int,
        answerType: Int,
        text: String
    ) {
        val tag = when (answerType) {
            1 -> "edit"
            2 -> "front"
            else -> "back"
        }
        inputPopupWindow = NewEditInputView(tag, requireContext())
        val textInfoBean = textInfoList[position]
        val childAt = binding.fl.getChildAt(position)
        currentRalY = textInfoBean.y
        inputPopupWindow.showNow(requireActivity().supportFragmentManager, "")
        inputPopupWindow.binding.edt.requestFocus()
        inputPopupWindow.binding.edt.setText(text)
        EditTextInputUtil.disableCopyAndPaste(inputPopupWindow.binding.edt)
        SoftInputUtils.setEditTextInputSpace(inputPopupWindow.binding.edt)
        inputPopupWindow.binding.edt.setSelection(text.length)
        activity.runOnUiThread {
            inputManager.showSoftInput(inputPopupWindow.binding.edt)
        }
//        Handler().postDelayed({ inputManager.showSoftInput() }, 10)
        inputPopupWindow.setStateListener(object : NewEditInputView.StateListener {
            override fun close() {
                childAt.findViewById<TextView>(R.id.tv_text).setBackgroundColor(Color.TRANSPARENT)
                dismissAnimation()
                Handler(Looper.getMainLooper()).post {
                    inputManager.hideALlSoftInput()
                }
                val answer = inputPopupWindow.binding.edt.text.toString().trim { it <= ' ' }
                if (answer.isNotEmpty()) {
                    if ((GenreID == 48 && GenreType == 2) || (GenreID == 46 && GenreType == 2)) {
                        if (hasAnswer(position)) {
                            val answerPosition = getAnswerPosition(position)
                            val view = tvMap[answerPosition]
                            askList.remove(textInfoList[answerPosition])
                            binding.flLayout.removeView(view)
                            tvMap.remove(answerPosition)
                            textInfoList[answerPosition].stuType = -1
                            textInfoList[answerPosition].stuAnswer = ""
//                        textInfoList[answerPosition].Index = "-1"
                            textInfoList[answerPosition].digitalAnswer = ""
                        }
                    } else {
                        if (hasAnswer(position)) {
                            val view = tvMap[position]
                            askList.remove(textInfoBean)
                            binding.flLayout.removeView(view)
                            tvMap.remove(position)
                        }
                    }
                    textInfoBean.stuAnswer = answer
                    textInfoBean.stuType = when (inputPopupWindow.binding.iv3rd.tag) {
                        "edit" -> 1
                        "front" -> 2
                        else -> 3
                    }
//                textInfoBean.Index = position.toString()
                    val answerStr = FormatUtil.toStr(position, textInfoList)
                    val str = FormatUtil.toArr(textInfoBean, answerStr)
                    textInfoBean.digitalAnswer = str
                    askList.add(textInfoBean)
                    insertStuAnswer(askList)
                    drawAnswer(position, textInfoBean, childAt, mutableListOf())
                }
            }
        })
        inputPopupWindow.binding.edt.setOnEditorActionListener { textView: TextView?, i: Int, keyEvent: KeyEvent? ->
            if (keyEvent != null && keyEvent.keyCode == KeyEvent.KEYCODE_ENTER || i == EditorInfo.IME_ACTION_DONE) {
                inputManager.hideKeyboard()
                inputPopupWindow.dismiss()
                return@setOnEditorActionListener true
            }
            false
        }
    }

    /*绘制保存的作答*/
    @SuppressLint("UseCompatLoadingForDrawables")
    private fun drawAnswer(
        position: Int,
        textInfo: TextInfo,
        child: View,
        list: MutableList<View>
    ) {
        val stuType = textInfo.stuType
        val stuAnswer = textInfo.stuAnswer
        val isFirst = isFirstPosition(position)
        when (stuType) {
            0, 1, 2, 3 -> {
                val answerView =
                    DrawView(false, isFirst, child, stuAnswer, "", stuType, 1, requireContext())
                binding.flLayout.addView(answerView)
                tvMap.put(position, answerView)
            }

            4 -> {
                val answerView = DrawView(
                    false,
                    isFirst,
                    if (list.size > 1) "本区域无错" else "无错",
                    "",
                    list,
                    4,
                    1,
                    requireContext()
                )
                binding.flLayout.addView(answerView)
                tvMap.put(position, answerView)
            }
        }
    }

    /*删除答案*/
    private fun deleteAnswer(
        startPosition: Int,
        endPosition: Int,
        position: Int
    ) {
        if (getAnswerType(position) == 4) {
            textInfoList.forEachIndexed { index, textInfo ->
                if (textInfo.Index in startPosition..endPosition) {
                    if (textInfoList[index].stuType != -1) {
                        askList.remove(textInfoList[index])
                        textInfoList[index].stuType = -1
                        textInfoList[index].stuAnswer = ""
//                    textInfoList[i].Index = "-1"
                        textInfoList[index].digitalAnswer = ""
                        val view = tvMap[index]
                        binding.flLayout.removeView(view)
                        tvMap.remove(index)
                        insertStuAnswer(askList)
//                    saveAnswerPic()
                    }
                }
            }
        } else {
            askList.remove(textInfoList[position])
            textInfoList[position].stuType = -1
            textInfoList[position].stuAnswer = ""
//            textInfoList[position].Index = "-1"
            textInfoList[position].digitalAnswer = ""
            val view = tvMap[position]
            binding.flLayout.removeView(view)
            tvMap.remove(position)
            insertStuAnswer(askList)
        }
    }

    /*插入作答信息*/
    private fun insertStuAnswer(list: ArrayList<TextInfo>) {
        val answerList =
            sameQuesDetail[index_A].ChildList!![0].ItemList!!
        for (itemBeanX in answerList) {
            itemBeanX.StuAnswer = ""
        }
        for (i in list.indices) {
            val position = list[i].Index
            val answer = list[i].digitalAnswer
            if (answerArea.size > 1) {
                for (j in answerArea.indices) {
                    //根据area区间插入作答
                    if (position in answerArea[j].AnswerArea!!.split(
                            "-"
                        )[0].toInt()..answerArea[j].AnswerArea!!.split(
                            "-"
                        )[1].toInt()
                    ) {
                        answerList[if (answerList.size > 1) j else 0].StuAnswer = answer
                    }
                }
            } else {
                if (answerList.size > 1) {
                    answerList.forEachIndexed { index, item ->
                        if (answerInfoList[index].Index == position) {
                            item.StuAnswer = answer
                        }
                    }
                } else {
                    answerList[0].StuAnswer = answer
                }
            }
        }
        if (answerList.size > 1 && answerArea.size <= 1) {
            for (i in list.indices) {
                for (j in answerList.indices) {
                    if (!isCorrectPosition(list[i].Index)) {
                        if (answerList[j].StuAnswer!!.isEmpty()) {
                            answerList[j].StuAnswer = list[i].digitalAnswer
                            break
                        }
                    }
                }
            }
        }
    }

    /**
     * 判断学生作答位置是否在参考答案位置
     */
    private fun isCorrectPosition(position: Int): Boolean {
        var b = false
        answerInfoList.forEach {
            if (it.Index == position) {
                b = true
            }
        }
        return b
    }

    /*该区域是否已作答*/
    private fun hasAnswer(position: Int): Boolean {
        var startPosition = -1
        var endPosition = -1
        var hasAnswer = false
        if ((GenreID == 48 && GenreType == 2) || (GenreID == 46 && GenreType == 2)) {
            answerArea.forEach {
                if (textInfoList[position].Index in it.AnswerArea!!.split("-")[0].toInt()..it.AnswerArea!!.split(
                        "-"
                    )[1].toInt()
                ) {
                    startPosition = it.AnswerArea!!.split("-")[0].toInt()
                    endPosition = it.AnswerArea!!.split("-")[1].toInt()
                }
            }
            for (i in startPosition..endPosition) {
                if (textInfoList[i].stuType != -1) {
                    hasAnswer = true
                }
            }
            return hasAnswer
        } else {
            return textInfoList[position].stuType != -1
        }
    }

    /*获取作答类型*/
    private fun getAnswerType(position: Int): Int {
        var startPosition = -1
        var endPosition = -1
        var answerType = -1
        if ((GenreID == 48 && GenreType == 2) || (GenreID == 46 && GenreType == 2)) {
            answerArea.forEach {
                if (textInfoList[position].Index in it.AnswerArea!!.split("-")[0].toInt()..it.AnswerArea!!.split(
                        "-"
                    )[1].toInt()
                ) {
                    startPosition = it.AnswerArea!!.split("-")[0].toInt()
                    endPosition = it.AnswerArea!!.split("-")[1].toInt()
                }
            }
            for (i in startPosition..endPosition) {
                if (textInfoList[i].stuType != -1) {
                    answerType = textInfoList[i].stuType
                }
            }
            return answerType
        } else {
            return textInfoList[position].stuType
        }
    }

    /*获取作答下标*/
    private fun getAnswerPosition(position: Int): Int {
        var startPosition = -1
        var endPosition = -1
        var answerPosition = -1
        if ((GenreID == 48 && GenreType == 2) || (GenreID == 46 && GenreType == 2)) {
            answerArea.forEach {
                if (textInfoList[position].Index in it.AnswerArea!!.split("-")[0].toInt()..it.AnswerArea!!.split(
                        "-"
                    )[1].toInt()
                ) {
                    startPosition = it.AnswerArea!!.split("-")[0].toInt()
                    endPosition = it.AnswerArea!!.split("-")[1].toInt()
                }
            }
            for (i in startPosition..endPosition) {
                if (textInfoList[i].stuType != -1) {
                    answerPosition = i
                }
            }
            return answerPosition
        } else {
            return position
        }
    }

    /*是否是区域第一个*/
    private fun isFirstPosition(position: Int): Boolean {
        var isFirst = false
        if (answerArea.size > 1) {
            answerArea.forEach {
                if (textInfoList[position].Index == it.AnswerArea!!.split("-")[0].toInt()) {
                    isFirst = true
                }
            }
        }
        return isFirst
    }

    override fun dismissPopupList() {
        if (!remaindStyle) {
            binding.fl.getChildAt(currentOperateIndex).findViewById<TextView>(R.id.tv_text)
                .setBackgroundColor(Color.TRANSPARENT)
        }
        remaindStyle = false
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        if (isVisibleToUser) {
            inputManager.hideKeyboard() //当软禁盘存在的时候自动消除软键盘
        }
    }

    override fun onPause() {
        super.onPause()
        requireActivity().window.decorView.viewTreeObserver.removeOnGlobalLayoutListener(
            mGlobalLayoutListener
        )
    }

    override fun onDestroy() {
        super.onDestroy()
        requireActivity().window.decorView.viewTreeObserver.removeOnGlobalLayoutListener(
            mGlobalLayoutListener
        )
    }
}